package com.glqiang.service.impl;

import com.glqiang.domain.vo.LoginUserVo;
import com.glqiang.domain.vo.LoginVo;
import com.glqiang.domain.vo.UserInfoVo;
import com.glqiang.response.ResponseResult;
import com.glqiang.security.CustomUserDetails;
import com.glqiang.security.authentication.phone.PhoneAuthenticationToken;
import com.glqiang.service.LoginService;
import com.glqiang.util.BeanCopyUtils;
import com.glqiang.util.JwtUtils;
import com.glqiang.util.RedisCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * @author glqiang
 * @date 2022/11/21 01:27
 */
@Service("loginService")
public class LoginServiceImpl implements LoginService {
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private RedisCache redisCache;

    @Override
    public ResponseResult<LoginUserVo> login(LoginVo loginVo) {
        Authentication authentication = null;
        switch (loginVo.getType()) {
            // 0 密码登录
            case 0: {
                if (!StringUtils.hasText(loginVo.getUsername())) {
                    return ResponseResult.error("用户名不能为空");
                }
                if (!StringUtils.hasText(loginVo.getPassword())) {
                    return ResponseResult.error("用户名不能为空");
                }
                authentication = authenticationManager
                        .authenticate(UsernamePasswordAuthenticationToken
                                .unauthenticated(loginVo.getUsername(), loginVo.getPassword()));
                break;
            }
            // 1 手机验证码登录
            case 1: {
                if (!StringUtils.hasText(loginVo.getPhone())) {
                    return ResponseResult.error("手机号不能为空");
                }
                if (!StringUtils.hasText(loginVo.getCode())) {
                    return ResponseResult.error("验证码不能为空");
                }
                authentication = authenticationManager
                        .authenticate(PhoneAuthenticationToken
                                .unauthenticated(loginVo.getPhone(), loginVo.getCode()));
                break;
            }
            default: {
                return ResponseResult.error("未指定登录类型");
            }
        }
        // 从loadUserByUsername方法中查到该用户的信息, 封装到UserDetails,
        // 之后又塞到了UsernamePasswordAuthenticationToken的Principal属性中
        assert authentication != null;
        // 这种使用接口实现登录的方式需要把用户信息存到redis中去
        CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();
        // 获取用户名生成token
        String username = userDetails.getUsername();
        String token = JwtUtils.getToken(username);
        // 把用户信息存入redis
        redisCache.setCacheObject("loginUser:" + username, userDetails);
        UserInfoVo userInfoVo = BeanCopyUtils.copyBean(userDetails.getUser(), UserInfoVo.class);
        return ResponseResult.success("登录成功", new LoginUserVo(token, userInfoVo));
    }
}
